#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Action classes.
"""

class ActionError(RuntimeError):
    """Exception for error related errors.
    """

class ActionManager(object):
    """Manages undoable and redoable actions.
    """

    def __init__(self):
        """Creates a new empty action queue.
	"""
	self.done_actions = []
        self.undone_actions = []

    def add(self, action):
        """Adds an action that have just been done.
        """
        self.undone_actions = []
        self.done_actions.append(action)

    def undo(self):
        """Undo the most recently added action.
        """
        if self.done_actions:
            action = self.done_actions.pop()
            action.undo()
            self.undone_actions.append(action)
        else:
            raise ActionError("No actions to undo.")

    def redo(self):
        """Redo last undone action.
        """
        if self.undone_actions:
            action = self.undone_actions.pop()
            action.redo()
            self.done_actions.append(action)
        else:
            raise ActionError("No actions to redo")


class DrawAction(object):
    """Draws free hand lines on a grid layer.
    """

    def __init__(self, target, brush):
        """Creates a drawing action.

        target: the grid layer to draw unto.
        brush: the value to put on the painted grid cells.
	"""
        self.target = target
        self.brush = brush
        self.history = {}

    def draw_cell(self, grid_pos, force=False):
        """Draws an individual cell on the grid layer. If force is
        True cell value is changed and previous valued saved on
        history even if it was already changed once.
        """
        # Only overwrite data if it wasn't painted already
        if force or grid_pos not in self.history:
            #self.history[grid_pos] = self.target.get_data(grid_pos)
            self.target.set_data(grid_pos, self.brush)

    def update(self, pos):
        """Updates the drawing action
        """
        # grid_pos = self.target.from_pixel(pos)
        # self.draw_cell(grid_pos)
        self.draw_cell(pos)

    def undo(self):
        """Undo the drawing or redo if called more than once.
        """
        for grid_pos, value in self.history.iteritems():
            self.draw_cell(grid_pos, value, force=True)

